package com.kehongborui.portal.config;

import com.alibaba.fastjson.JSON;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author zhang peng yang ming
 * @CopyRight (C) http://www.csdn.com
 * @brief
 * @email 122162005@qq.com
 * @date 2018-09-30
 */
public class SczcWebSocketHandler extends TextWebSocketHandler {
    private static final CopyOnWriteArraySet<WebSocketSession> users;//这个会出现性能问题，最好用Map来存储，key用userid
    static {
        users = new CopyOnWriteArraySet<WebSocketSession>();
    }

    public SczcWebSocketHandler() {
    }

    /**
     * 连接成功时候，会触发页面上onopen方法
     */
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("connect to the websocket success......当前数量:" + users.size());
        users.add(session);
        //这块会实现自己业务，比如，当用户登录后，会把离线消息推送给用户
        //TextMessage returnMessage = new TextMessage("你将收到的离线");
        HashMap<Object, Object> map = new HashMap<>();
        map.put("key", "value");
        session.sendMessage(new TextMessage(JSON.toJSONString(map)));
    }

    /**
     * 关闭连接时触发
     */
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        String username = (String) session.getAttributes().get("WEBSOCKET_USERNAME");
        System.out.println("用户" + username + "已退出！");
        users.remove(session);
        System.out.println("剩余在线用户" + users.size());
    }

    /**
     * js调用websocket.send时候，会调用该方法
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
    }

    /**
     * 连接出错时调用
     */
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if(session.isOpen()){session.close();}
        users.remove(session);
    }

    public boolean supportsPartialMessages() {
        return false;
    }


    /**
     * 给某个用户发送消息
     *
     * @param userName
     * @param message
     */
    public void sendMessageToUser(String userName, TextMessage message) {
        for (WebSocketSession user : users) {
            if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) {
                try {
                    if (user.isOpen()) {
                        user.sendMessage(message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

    /**
     * 给所有查看上传状态的用户发送消息
     *
     * @param message
     */
    public void sendMessageToUploadUsers(String message) {
        this.sendMessageToUsers(new TextMessage(message), SocketUri.W_FIELD_TEMP, SocketUri.S_FIELD_TEMP);
    }

    /**
     * 给所有用户发送消息
     *
     * @param message 要发送的文本消息
     * @param wUri spring websocket 服务端地址
     * @param sUsi SockJS websocket 服务端地址
     */
    public void sendMessageToUsers(TextMessage message, String wUri, String sUsi) {
        for (WebSocketSession user : users) {
            try {
                if (user.isOpen()) {
                    if(user.getUri().toString().endsWith(wUri) || user.getUri().toString().endsWith(sUsi)) {
                        user.sendMessage(message);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
